package x10doc.doc; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import polyglot.types.ClassType; import polyglot.types.Ref; import x10.ast.X10SourceFile_c; import x10.types.ParameterType; import x10.types.TypeDef; import x10.types.X10ClassDef; import x10.types.X10ConstructorDef; import x10.types.X10FieldDef; import x10.types.X10MethodDef; import polyglot.types.TypeSystem; import x10.types.constraints.CConstraint; import x10.types.constraints.SubtypeConstraint; import x10.types.constraints.TypeConstraint; import com.sun.javadoc.AnnotationDesc; import com.sun.javadoc.AnnotationTypeDoc; import com.sun.javadoc.ClassDoc; import com.sun.javadoc.ConstructorDoc; import com.sun.javadoc.FieldDoc; import com.sun.javadoc.MemberDoc; import com.sun.javadoc.MethodDoc; import com.sun.javadoc.PackageDoc; import com.sun.javadoc.ParamTag; import com.sun.javadoc.ParameterizedType; import com.sun.javadoc.ProgramElementDoc; import com.sun.javadoc.Type; import com.sun.javadoc.TypeVariable; import com.sun.javadoc.WildcardType; public class X10ClassDoc extends X10Doc implements ClassDoc { X10SourceFile_c source; X10ClassDef classDef; X10ClassDoc containingClass; X10ClassDoc superclass; Type superclassType; X10PackageDoc containingPackage; X10RootDoc rootDoc; Map<String, X10TypeVariable> typeParams; Map<String, X10FieldDoc> fields; Map<String, X10ConstructorDoc> constructors; Map<String, MethodDoc> methods; List<X10ClassDoc> innerClasses; List<X10ClassDoc> interfaces; List<Type> interfaceTypes; boolean included; X10FieldDoc[] includedFields; X10ConstructorDoc[] includedConstructors; MethodDoc[] includedMethods; // MethodDoc not X10MethodDoc, because X10TypeDefDoc (which implements MethodDoc) // objects are also methods; applies to field "methods" also X10ClassDoc[] includedInnerClasses; public X10ClassDoc(X10ClassDef classDef, X10ClassDoc containingClass, String comment) { //super(comment); this.classDef = classDef; this.containingClass = containingClass; this.rootDoc = X10RootDoc.getRootDoc(); this.fields = new LinkedHashMap<String, X10FieldDoc>(); this.constructors = new LinkedHashMap<String, X10ConstructorDoc>(); this.methods = new LinkedHashMap<String, MethodDoc>(); this.innerClasses = new ArrayList<X10ClassDoc>(); this.interfaces = new ArrayList<X10ClassDoc>(); this.interfaceTypes = new ArrayList<Type>(); this.included = false; this.includedFields = null; this.superclass = null; this.superclassType = null; initTypeParameters(); super.processComment(comment); // addDeclTag(declString()); } public MemberDoc getMemberDoc(String name){ for(X10FieldDoc doc: fields.values()){ if (doc.name().equals(name)) return doc; } String shortname = name; String signature = "()"; int index = name.indexOf("("); if (index != -1) { shortname = name.substring(0,name.indexOf("(")); signature = name.substring(index); signature = makeQualifiedParams(signature); } index = shortname.indexOf("["); if(index != -1) { shortname = shortname.substring(0, index); } for(X10ConstructorDoc doc: constructors.values()){ if (doc.name().equals(shortname) && doc.signature().equals(signature)){ return doc; } } for(MethodDoc doc: methods.values()){ String n = doc.name(); String s= doc.signature(); if (doc.name().equals(shortname) && doc.signature().equals(signature)){ return doc; } } return null; } private String makeQualifiedParams(String signature) { String sig = ""; String delim = "(),>"; StringTokenizer tok = new StringTokenizer(signature, delim, true); while (tok.hasMoreTokens()) { String token = tok.nextToken(); if (delim.contains(token)) { sig += token; if (token.equals(">")) { sig += " "; } } else { token = token.trim(); if (token.length() > 0) { X10ClassDoc doc = X10RootDoc.getRootDoc().findClass(this, token.trim()); if (doc != null) { sig += doc.qualifiedName(); } else { sig += token; } } } } return sig; } public void setSuperclass(X10ClassDoc superclass) { this.superclass = superclass; } public void setSuperclassType(Type superclassType) { this.superclassType = superclassType; } void initTypeParameters() { List<ParameterType> params = classDef.typeParameters(); typeParams = new LinkedHashMap<String, X10TypeVariable>(params.size()); Ref<CConstraint> inv = classDef.classInvariant(); // System.out.println("classInvariant: " + ((inv == null) ? "" : inv.get())); TypeConstraint c = classDef.typeGuard().get(); for (ParameterType p: params) { X10TypeVariable v = new X10TypeVariable(p, this); v.setTypeGuard(c); typeParams.put(typeParameterKey(p), v); } // the following are commented because classDef.{classInvariant, typeBounds} etc. returns // null for x10.lang.Ref // System.out.println("TypeBounds: " + classDef.typeBounds().get()); // System.out.println("TypeGuard: " + classDef.typeGuard().get()); for (SubtypeConstraint s: classDef.typeGuard().get().terms()) { // System.out.println("SubtypeConstraint: " + s); } } // initializations that are common to specified and unspecified classes; this method initializes classes, interfaces // and packages related to this class, e.g., super classes, implemented interfaces, containing package; calls from // here may set off a chain of recursive calls, e.g., creation of ClassDoc objects for all ancestor classes of this // class public void initializeRelatedEntities() { // set package of class String path = classDef.position().file().replace(".x10", ""); if (classDef.name() != null) { path = path.replace(classDef.name().toString(), ""); } this.containingPackage = rootDoc.getPackage(classDef.package_(), path); this.containingPackage.addClass(this); // obtain ClassDoc and Type objects for superclass Ref<? extends polyglot.types.Type> reft = classDef.superType(); polyglot.types.Type t = ((reft==null) ? null : reft.get()); X10ClassDef cdef = (X10ClassDef) ((t == null) ? null : t.toClass().def()); this.superclass = rootDoc.getUnspecClass(cdef); this.superclassType = rootDoc.getType(t); // add interfaces implemented by the class addInterfaces(); } public void addInterfaces() { for (Ref<? extends polyglot.types.Type> ref: classDef.interfaces()) { this.interfaces.add(rootDoc.getUnspecClass((X10ClassDef) ref.get().toClass().def())); this.interfaceTypes.add(rootDoc.getType(ref.get())); } // System.out.println("---- start interface tree ----"); // System.out.println("X10ClassDoc{" + classDef + "}.interfaceTypes = " + // Arrays.toString(interfaceTypes.toArray(new Type[0]))); // for (Type y: interfaceTypes) { // printInterfaceTree(y); // } // System.out.println("---- end interface tree ----"); } public static void printInterfaceTree(Type t) { if (t instanceof X10ParameterizedType) { X10ParameterizedType x = (X10ParameterizedType)t; System.out.println("X10ParameterizedType{" + x + "}.interfaceTypes = " + Arrays.toString(x.interfaceTypes())); for (Type y: x.interfaceTypes()) { printInterfaceTree(y); } } } public String declString() { // a declaration is needed if the class has associated constraints, or extends classes, implements interfaces that // are X10 specific (contain closures, constraints) Ref<CConstraint> refC = classDef.classInvariant(); Ref<TypeConstraint> refG = classDef.typeGuard(); boolean needsDeclForSuperOrInt = false; // signifies that the declaration is needed because either the super class // or an implemented interface is X10-specific, as opposed to it being needed // because of associated class constraints if (!(X10Type.isX10Specific(this.superclassType))) { needsDeclForSuperOrInt = false; for (Type t: this.interfaceTypes) { if (X10Type.isX10Specific(t)) { needsDeclForSuperOrInt = true; break; } } } else { needsDeclForSuperOrInt = true; } if ((refC == null) && (refG == null) && !needsDeclForSuperOrInt) { return null; } String temp = classDef.asType().toString(); String result = "<B>Declaration</B>: <TT>" + name(); TypeVariable[] params = typeParameters(); if (refG != null && (params.length > 0)) { result += Arrays.toString(params); } String constraint = "{"; if (refC != null) { refC.get(); refC = classDef.classInvariant(); // attempt to force lazy initialization String inv = refC.get().toString(); int len = inv.length(); if (len > 2) { constraint += inv.substring(1, len-2); // remove leading '{', trailing '}' if (refG != null) { constraint += ", "; } } } if (refG != null) { // String typeGuard = refG.get().toString(); // int len = typeGuard.length(); // if (len > 2) { // constraint += typeGuard.substring(1, len-2); // remove leading '[', trailing ']' // } boolean first = true; for (SubtypeConstraint st: refG.get().terms()) { // Type sub = rootDoc.getType(st.subtype()); // Type sup = rootDoc.getType(st.supertype()); if (first) { first = false; } else { constraint += ", "; } // constraint += linkTag(st.subtype()) + " <: " + linkTag(st.supertype()); constraint += st.toString(); } } if (!constraint.equals("{")) { result += constraint + "}"; } else if (!needsDeclForSuperOrInt) { // the declaration string is not needed for super classes or implemented interfaces, and there are // no class constraints to display return null; } if (this.superclass != null) { result += " extends " + this.superclass.classDef; } if (this.interfaceTypes.size() > 0) { result += (this.isInterface() ? " extends " : " implements "); boolean first = true; for (Type t: this.interfaceTypes) { if (first) { first = false; result += X10Type.toString(t); } else { result += ", " + X10Type.toString(t); } } } result += ".</TT><PRE>\n</PRE>"; // the period before <TT> is required because the declaration string is // added as a prefix to the first sentence, and is displayed in the // "Class Summary" table, where newlines are replaced with single spaces; // the period separates the declaration from the first sentence in the // "Class Summary" section return result; } public String linkTag(polyglot.types.Type t) { // if (t instanceof X10TypeVariable) { // return ("{@link " + name() + " " + ((X10TypeVariable) t).typeName() + "}"); // } // else if (t instanceof X10ClassDoc) { // X10ClassDoc cd = ((X10ClassDoc) t); // if (cd.isIncluded()) { // return ("{@link " + cd.qualifiedName() + " " + cd.name() + "}"); // } // else { // return cd.name(); // } // } // else { // return t.typeName(); // } if (t instanceof ParameterType) { ParameterType p = (ParameterType) t; return ("{@link " + name() + " " + ((ParameterType) t).name().toString() + "}"); } X10ClassDef classDef = (X10ClassDef) t.toClass().def(); if (classDef.typeParameters().size() == 0) { X10ClassDoc cd = (X10ClassDoc) rootDoc.getClass(classDef); if (cd == null) { return classDef.fullName().toString(); } else { if (cd.isIncluded()) { return ("{@link " + cd.qualifiedName() + " " + cd.name() + "}"); } else { return cd.name(); } } } else { return t.toString(); } } public void addDeclsToMemberComments() { for (FieldDoc fd: fields.values()) { X10Doc d = (X10Doc) fd; d.addDeclTag(d.declString()); } for (ConstructorDoc doc: constructors.values()) { X10Doc d = (X10Doc) doc; d.addDeclTag(d.declString()); } for (MethodDoc md: methods.values()) { X10Doc d = (X10Doc) md; d.addDeclTag(d.declString()); } } public static String fieldKey(X10FieldDef fd) { return fd.name().toString(); } public static String methodKey(X10ConstructorDef cd) { return cd.signature(); } public static String methodKey(X10MethodDef md) { // return md.name().toString() + X10MethodDoc.signature(md); return md.signature(); } public static String methodKey(TypeDef td) { // return md.name().toString() + X10MethodDoc.signature(md); return td.signature(); } public static String typeParameterKey(ParameterType p) { return p.name().toString(); } public void setSource(X10SourceFile_c source) { this.source = source; } public X10FieldDoc updateField(X10FieldDef fdef, String comments) { X10FieldDoc fd = getField(fdef); if (fd == null) { fd = new X10FieldDoc(fdef, this, comments); fields.put(fieldKey(fdef), fd); } else { String existingCmnt = fd.commentText(); assert(existingCmnt.equals("") || existingCmnt.equals(comments)) : "X10ClassDoc.updateField(" + fieldKey(fdef) + ",...): mismatch between existing and given comments"; // fd.setIncluded(true); fd.setRawCommentText(comments); } return fd; } public X10ConstructorDoc updateConstructor(X10ConstructorDef cdef, String comments) { X10ConstructorDoc cd = getConstructor(cdef); if (cd == null) { cd = new X10ConstructorDoc(cdef, this, comments); constructors.put(methodKey(cdef), cd); } else { String existingCmnt = cd.commentText(); assert(existingCmnt.equals("") || existingCmnt.equals(comments)) : "X10ClassDoc.updateConstructor(" + methodKey(cdef) + ",...): mismatch between existing and given comments"; // cd.setIncluded(true); cd.setRawCommentText(comments); } return cd; } public MethodDoc updateMethod(X10MethodDef mdef, String comments) { MethodDoc md = getMethod(mdef); if (md == null) { md = new X10MethodDoc(mdef, this, comments); methods.put(methodKey(mdef), md); } else { String existingCmnt = md.commentText(); assert(existingCmnt.equals("") || existingCmnt.equals(comments)) : "X10ClassDoc.updateMethod(" + methodKey(mdef) + ",...): mismatch between existing and given comments"; // md.setIncluded(true); // commented to avoid duplicate addition of declaration comments // TODO: determine what needs to be done here or use another method/method name md.setRawCommentText(comments); } return md; } public MethodDoc updateTypeDef(TypeDef tdef, String comments) { MethodDoc td = getMethod(tdef); if (td == null) { td = new X10TypeDefDoc(tdef, this, comments); methods.put(methodKey(tdef), td); } else { String existingCmnt = td.commentText(); assert(existingCmnt.equals("") || existingCmnt.equals(comments)) : "X10ClassDoc.updateTypeDef(" + methodKey(tdef) + ",...): mismatch between existing and given comments"; // td.setIncluded(true); // commented to avoid duplicate addition of declaration comments // TODO: determine what needs to be done here or use another method/method name td.setRawCommentText(comments); } return td; } public void addInnerClass(X10ClassDoc cd) { innerClasses.add(cd); if (X10RootDoc.printSwitch) System.out.println("X10ClassDoc.addInnerClass(" + cd.name() + "); innerClasses.size() = " + innerClasses.size()); } public void addInterface(X10ClassDoc intClassDoc) { interfaces.add(intClassDoc); } // set this.included according to the access modifier filter public void setIncluded() { this.included = X10Doc.isIncluded(rootDoc.accessModFilter(), this); } public void setPackage(X10PackageDoc pkg) { this.containingPackage = pkg; } public X10FieldDoc getField(String name) { return fields.get(name); } public X10FieldDoc getField(X10FieldDef fdef) { return fields.get(fieldKey(fdef)); } public X10ConstructorDoc getConstructor(String name) { return constructors.get(name); } public X10ConstructorDoc getConstructor(X10ConstructorDef cdef) { return constructors.get(methodKey(cdef)); } public MethodDoc getMethod(String name) { return methods.get(name); } public MethodDoc getMethod(X10MethodDef mdef) { // System.out.println("X10ClassDoc.getMethod: methods.keySet() = " + Arrays.toString(methods.keySet().toArray(new String[0]))); return methods.get(methodKey(mdef)); } public MethodDoc getMethod(TypeDef tdef) { return methods.get(methodKey(tdef)); } public X10TypeVariable getTypeVariable(ParameterType p) { return typeParams.get(typeParameterKey(p)); } public AnnotationDesc[] annotations() { // TODO Auto-generated method stub return new AnnotationDesc[0]; } // Return this type as an AnnotationTypeDoc if it represents an annotation type, null otherwise. public AnnotationTypeDoc asAnnotationTypeDoc() { return null; } public ClassDoc asClassDoc() { return this; } public ParameterizedType asParameterizedType() { return null; } public TypeVariable asTypeVariable() { return null; } public WildcardType asWildcardType() { return null; } public ConstructorDoc[] constructors() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.constructors() called for "+name()); // return constructors.values().toArray(new ConstructorDoc[0]); // HACK: it seems that the standard doclet does not call X10ClassDoc.constructors(boolean) for the desired // set of included constructors; so, force a call to it from here return constructors(true); } public ConstructorDoc[] constructors(boolean arg0) { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.constructors(boolean) called for "+name()); if (arg0) { if (includedConstructors != null) { return includedConstructors; } int size = 0; Collection<X10ConstructorDoc> constrSet = constructors.values(); for (ConstructorDoc cd: constrSet) { if (cd.isIncluded()) { size++; } } includedConstructors = new X10ConstructorDoc[size]; int i = 0; for (X10ConstructorDoc cd: constrSet) { if (cd.isIncluded()) { includedConstructors[i++] = cd; } } return includedConstructors; } return constructors(); } public ClassDoc containingClass() { return containingClass; } public PackageDoc containingPackage() { if (X10RootDoc.printSwitch) { System.out.print("ClassDoc.containingPackage() called for "+name()); // new Exception().printStackTrace(); System.out.println("; containingPackage.name() = " + containingPackage.name()); } return containingPackage; } public boolean definesSerializableFields() { // TODO Auto-generated method stub return false; } public String dimension() { ClassType classType = classDef.asType(); return (classType.isArray() ? String.valueOf(classType.toArray().dims()) : ""); } public FieldDoc[] enumConstants() { // TODO Auto-generated method stub return new FieldDoc[0]; } public FieldDoc[] fields() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.fields() called. fields.size() = " + fields.size()); return fields.values().toArray(new FieldDoc[0]); } public FieldDoc[] fields(boolean arg0) { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.fields(boolean) called for "+name()); if (arg0) { if (includedFields != null) { return includedFields; } int size = 0; Collection<X10FieldDoc> fieldsSet = fields.values(); for (X10FieldDoc fd: fieldsSet) { if (fd.isIncluded()) { size++; } } includedFields = new X10FieldDoc[size]; int i = 0; for (X10FieldDoc fd: fieldsSet) { if (fd.isIncluded()) { includedFields[i++] = fd; } } return includedFields; } return fields(); } public ClassDoc findClass(String arg0) { // TODO Auto-generated method stub return rootDoc.classNamed(arg0); } public ClassDoc[] importedClasses() { // TODO Auto-generated method stub if (X10RootDoc.printSwitch) System.out.println("ClassDoc.importedClasses() called for "+name()); return new ClassDoc[0]; } public PackageDoc[] importedPackages() { // TODO Auto-generated method stub if (X10RootDoc.printSwitch) System.out.println("ClassDoc.importedPackages() called for "+name()); return new PackageDoc[0]; } public ClassDoc[] innerClasses() { if (X10RootDoc.printSwitch) System.out.println("" + name() + ".innerClasses() called; innerClasses.size() = " + innerClasses.size()); return innerClasses.toArray(new ClassDoc[0]); } public ClassDoc[] innerClasses(boolean arg0) { if (X10RootDoc.printSwitch) System.out.println("" + name() + ".innerClasses() called; innerClasses.size() = " + innerClasses.size()); // return innerClasses.toArray(new ClassDoc[0]); if (arg0) { if (includedInnerClasses != null) { return includedInnerClasses; } int size = 0; // Collection<X10ClassDoc> classes = innerClasses.values(); for (X10ClassDoc cd: innerClasses) { if (cd.isIncluded()) { size++; } } includedInnerClasses = new X10ClassDoc[size]; int i = 0; for (X10ClassDoc cd: innerClasses) { if (cd.isIncluded()) { includedInnerClasses[i++] = cd; } } return includedInnerClasses; } return innerClasses(); } /** * Return interfaces implemented by this class or interfaces extended by this interface. * Includes only directly-declared interfaces, not inherited interfaces. */ public ClassDoc[] interfaces() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.interfaces() called for "+name()); return interfaces.toArray(new ClassDoc[0]); } /** * Return interfaces implemented by this class or interfaces extended by this interface. * Includes only directly-declared interfaces, not inherited interfaces. */ public Type[] interfaceTypes() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.interfaceTypes() called for "+name()); // needs to be updated to handle generic types; the result is an array of ClassDoc // or ParametrizedType objects return interfaceTypes.toArray(new Type[0]); } public boolean isAbstract() { return (classDef.flags().isAbstract() || isInterface()); } public boolean isClass() { return (!isInterface()); } @Override public boolean isAnnotationType() { // X10TypeSystem ts = (X10TypeSystem) classDef.typeSystem(); // try { // return ts.isSubtype(classDef.asType(), (polyglot.types.Type) ts.forName(QName.make("x10.lang.annotations.Annotation")), ts.emptyContext()); // } catch (SemanticException e) { return false; // } } @Override public boolean isEnum() { // TODO Auto-generated method stub return super.isEnum(); } @Override public boolean isError() { TypeSystem ts = (TypeSystem) classDef.typeSystem(); return ts.isSubtype(classDef.asType(), ts.Error(), ts.emptyContext()); } @Override public boolean isException() { TypeSystem ts = (TypeSystem) classDef.typeSystem(); return ts.isSubtype(classDef.asType(), ts.Exception(), ts.emptyContext()); } @Override public boolean isIncluded() { return included; } @Override public boolean isInterface() { return classDef.flags().isInterface(); } // the following assumes that isEnum, isError, isException have been called earlier @Override public boolean isOrdinaryClass() { return !classDef.flags().isInterface(); } public boolean isPackagePrivate() { return classDef.flags().isPackage(); } public boolean isPrimitive() { // nothing in X10 is primitive return false; } public boolean isPrivate() { return classDef.flags().isPrivate(); } public boolean isProtected() { return classDef.flags().isProtected(); } public boolean isPublic() { return classDef.flags().isPublic(); } public boolean isSerializable() { // X10's notion of serialization is different from that of Java return false; } public boolean isStatic() { return classDef.flags().isStatic(); } public MethodDoc[] methods() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.methods() called for "+name()); return methods.values().toArray(new MethodDoc[0]); } public MethodDoc[] methods(boolean arg0) { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.methods(boolean) called for "+name()); if (arg0) { if (includedMethods != null) { return includedMethods; } int size = 0; Collection<MethodDoc> methodsSet = methods.values(); for (MethodDoc md: methodsSet) { if (md.isIncluded()) { size++; } } includedMethods = new MethodDoc[size]; int i = 0; for (MethodDoc md: methodsSet) { if (md.isIncluded()) { includedMethods[i++] = (MethodDoc)md; } } return includedMethods; } return methods(); } public String modifiers() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.modifiers() called for "+name()); return classDef.flags().toString(); } public int modifierSpecifier() { return X10Doc.flagsToModifierSpecifier(classDef.flags().flags()); } public String name() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.name() called for "+classDef.name()); String contClassName = ((containingClass == null) ? "" : (containingClass.name() + ".")); return (contClassName + (classDef.isAnonymous() ? "<anonymous class>" : classDef.name().toString())); // return (contClassName + classDef.name().toString() + // classDef.classInvariant().get() + classDef.typeBounds().get()); } public String qualifiedName() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.qualifiedName() called for "+name()); return classDef.fullName().toString(); // classDef.toString() also returns the fully qualified name // return classDef.asType().toString(); // return "!!X10ClassDoc:qualifiedName!!"; } public String qualifiedTypeName() { // classDef.asType().toString() = classDef.asType().fullName().toString() // for ValRail[Place]{...} String result = classDef.asType().fullName().toString(); if (X10RootDoc.printSwitch) System.out.println("ClassDoc{" + name() + "}.qualifiedTypeName() = " + result); return "!!X10ClassDoc:qualifiedTypeName!!"; } public FieldDoc[] serializableFields() { // TODO Auto-generated method stub if (X10RootDoc.printSwitch) System.out.println("ClassDoc.serializableFields() called for "+name()); return new FieldDoc[0]; } public MethodDoc[] serializationMethods() { // TODO Auto-generated method stub if (X10RootDoc.printSwitch) System.out.println("ClassDoc.serializationMethods() called for "+name()); return new MethodDoc[0]; } public String simpleTypeName() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.simpleTypeName() called for "+name()); return name(); // return "X10ClassDoc!!simpleTypeName!!"; } public boolean subclassOf(ClassDoc arg0) { // TODO Auto-generated method stub return false; } public ClassDoc superclass() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.superClass() called for "+name()); if (isInterface()) { return null; } // HACK: Sidestep a bug in Javadoc 1.6 tool where the code in // com.sun.tools.doclets.internal.toolkit.util.Util Util.getFirstVisibleSuperClass // assumes that every class is either public or has a public ancestor // superclass. This is not true in X10 and since it is not viable to fix // the bug in javadoc, we instead lie here and if all superclasses of this // class are not public, we lie are return null (indicating that this class // is the top of its hierarchy). if (superclass == null) return superclass; if (superclass.isPublic()) return superclass; X10ClassDoc sc = superclass; while (sc != null && !sc.isPublic()) { sc = sc.superclass; } return sc; } public Type superclassType() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.superClassType() called for "+name()); if (isInterface()) { return null; } // HACK: Sidestep a bug in Javadoc 1.6 tool where the code in // com.sun.tools.doclets.internal.toolkit.util.Util Util.getFirstVisibleSuperClass // assumes that every class is either public or has a public ancestor // superclass. This is not true in X10 and since it is not viable to fix // the bug in javadoc, we instead lie here and if all superclasses of this // class are not public, we lie are return null (indicating that this class // is the top of its hierarchy). if (superclassType == null) return superclassType; Type st = superclassType; while (st instanceof X10ClassDoc) { X10ClassDoc stdoc = (X10ClassDoc) st.asClassDoc(); if (stdoc.isPublic()) return st; st = stdoc.superclassType; } return st; } public String typeName() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.typeName() called for "+name()); // return classDef.asType().fullName().toString(); return "!!X10ClassDoc:TYPENAME!!"; } public TypeVariable[] typeParameters() { if (X10RootDoc.printSwitch) System.out.println("ClassDoc.typeParameters() called for "+name()); return typeParams.values().toArray(new TypeVariable[0]); } public ParamTag[] typeParamTags() { // TODO Auto-generated method stub if (X10RootDoc.printSwitch) System.out.println("ClassDoc.typeParamTags() called for "+name()); return new ParamTag[0]; } public String toString() { return name() + classDef.classInvariant().get() + classDef.typeBounds().get(); } public boolean isExternalizable() { // TODO Auto-generated method stub return false; } public boolean isFinal() { return classDef.flags().isFinal(); } // public static String fieldKey(X10FieldDoc fd) { // return fd.name(); //} // //public static String methodKey(X10ConstructorDoc cd) { // return methodKey(cd.getConstructorDef()); //} // //public static String methodKey(X10MethodDoc m) { // return methodKey(m.getMethodDef()); //} // public X10FieldDoc addField(X10FieldDoc fd) { // String name = fieldKey(fd); // X10FieldDoc existingFD = fields.get(name); // if (existingFD != null) // return existingFD; // else { // fields.put(fd.name(), fd); // return fd; // } //} // //public X10ConstructorDoc addConstructor(X10ConstructorDoc cd) { // String name = methodKey(cd); // X10ConstructorDoc existingCD = constructors.get(name); // if (existingCD != null) // return existingCD; // else { // constructors.put(name, cd); // return cd; // } //} // //public X10MethodDoc addMethod(X10MethodDoc md) { // String sig = methodKey(md); // X10MethodDoc existingMD = methods.get(sig); // if (existingMD != null) // return existingMD; // else { // methods.put(sig, md); // return md; // } //} // this method is intended to initialize fields such as includedFields, includedMethods, but class cast exceptions // were thrown when converting ProgramElementDoc[] to X10FieldDoc[] in // "includedFields = (X10FieldDoc[]) includedMembers(fields.values())" public static ProgramElementDoc[] includedMembers(Collection<? extends ProgramElementDoc> values) { int size = 0; for (ProgramElementDoc pd: values) { if (pd.isIncluded()) { size++; } } ProgramElementDoc[] result = new ProgramElementDoc[size]; int i = 0; for (ProgramElementDoc pd: values) { if (pd.isIncluded()) { result[i++] = pd; } } return result; } }